package com.yxw.yxnet_cd_center.customer_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.enums.CodeRuleEnum;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import com.yxw.yxnet_cd_center.customer_service.dto.GroupAddDTO;
import com.yxw.yxnet_cd_center.customer_service.dto.GroupQueryDTO;
import com.yxw.yxnet_cd_center.customer_service.dto.StatusUpdateDTO;
import com.yxw.yxnet_cd_center.customer_service.entity.*;
import com.yxw.yxnet_cd_center.customer_service.mapper.*;
import com.yxw.yxnet_cd_center.customer_service.service.CodeRuleService;
import com.yxw.yxnet_cd_center.customer_service.service.GroupService;
import com.yxw.yxnet_cd_center.customer_service.utils.PageUtils;
import com.yxw.yxnet_cd_center.customer_service.utils.UserUtil;
import com.yxw.yxnet_cd_center.customer_service.vo.MemberVo;
import com.yxw.yxnet_cd_center.customer_service.vo.UserRuleVo;
import com.yxw.yxnet_cd_center.customer_service.vo.YxCsGroupVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工作组管理
 * @author liuxin
 * @date 2023.09.15
 */
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, YxCsGroupEntity> implements GroupService {

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private UserMapper uerMapper;

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private CodeRuleService codeRuleService;

    @Autowired
    private FlockMapper  flockMapper;

    @Autowired
    private YxCsFlowRuleMapper yxCsFlowRuleMapper;

    @Autowired
    private YxScFlowRuleUserMapper yxScFlowRuleUserMapper;

    @Autowired
    private YxCsFlockUserMapper yxCsFlockUserMapper;

    @Autowired
    private YxCsGroupUserMapper yxCsGroupUserMapper;

    /**
     * 查询用户组列表
     * @param dto
     * @return
     */
    @Override
    public PageVO<YxCsGroupVo> getGroupList(GroupQueryDTO dto) {
        Page<YxCsGroupEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        LambdaQueryWrapper<YxCsGroupEntity> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(dto.getGroupName())){
            queryWrapper.like(true, YxCsGroupEntity::getGroupName, dto.getGroupName().trim());
        }
        queryWrapper.ge(StringUtils.isNotBlank(dto.getCreateTimeStart()), YxCsGroupEntity::getCreateTime, BaseDateTime.getDate(dto.getCreateTimeStart()))
                .le(StringUtils.isNotBlank(dto.getCreateTimeEnd()), YxCsGroupEntity::getCreateTime, BaseDateTime.getDate(dto.getCreateTimeEnd()))
                .eq(null!=dto.getStatus(),YxCsGroupEntity::getStatus,dto.getStatus())
        .orderByDesc(YxCsGroupEntity::getCreateTime);
        page = baseMapper.selectPage(page, queryWrapper);
        List<YxCsGroupEntity> entityList = page.getRecords();
        List<YxCsGroupVo> listVoList=new ArrayList<>();
        if(null!=entityList && !entityList.isEmpty()){
            listVoList = BeanUtil.copyToList(entityList, YxCsGroupVo.class);
        }
        return PageUtils.get(page,listVoList);
    }
    /**
     * 工作流管理-新增工作组
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public YxCsGroupVo addGroup(GroupAddDTO dto) {
        this.validateGroupInfo(dto);
        YxCsGroupEntity entity = new YxCsGroupEntity();
        BeanUtil.copyProperties(dto,entity);
        //获取编码,循环五次调用防止编码重复,循环写在编码获取方法时不生效
        String  code="";
        for(int i = 0; i <5 ; i++) {
            code = codeRuleService.buildCode(dto.getGroupName(),CodeRuleEnum.group_code_rule);
            if(StringUtils.isNotBlank(code)){
                break;
            }
        }
        if(StringUtils.isBlank(code)){
            throw  new BaseException("工作组编码生成异常");
        }
        //组装基本参数
        entity.setGroupCode(code);
        entity.setCreateId(userUtil.getLoginUserId());
        entity.setCreateName(userUtil.getLoginName());
        entity.setCreateTime(new Date());
        entity.setStatus(null==entity.getStatus()?CommonConstant.ZERO:entity.getStatus());
        //责任人名称
        YxCsUserEntity userEntity = uerMapper.selectById(dto.getLeaderId());
        if(null!=userEntity){
            entity.setLeaderName(userEntity.getUserName());
        }
        //渠道名称
        YxCsChannelEntity channelEntity = channelMapper.selectById(dto.getChannelId());
        if(null!=channelEntity){
            entity.setChannelName(channelEntity.getChannelName());
            entity.setChannelCode(channelEntity.getChannelCode());
        }
        baseMapper.insert(entity);
        //保存组成员到中间表
        groupMapper.addGroupUser(entity.getId(),dto.getUserIdList());
        YxCsGroupVo vo = new YxCsGroupVo();
        BeanUtil.copyProperties(entity,vo);
        return vo;
    }

    /**
     * 更新工作组
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGroup(GroupAddDTO dto) {
        //校验人员是否变更-针对删除的那部分人是否撇配的规则没有人的情况
        validataRuleUser(dto);
        if(null==dto.getId()){
            throw new BaseException("更新主键不能为空");
        }
        if(null==dto.getStatus()){
            throw new BaseException("组状态不能为空");
        }
        YxCsGroupEntity entity = groupMapper.selectById(dto.getId());
        if(null==entity){
            throw new BaseException("未查询到需要更新的工作组");
        }
        this.validateGroupInfo(dto);
        BeanUtil.copyProperties(dto,entity);
        entity.setUpdateId(userUtil.getLoginUserId());
        entity.setUpdateName(userUtil.getLoginName());
        entity.setUpdateTime(new Date());
        //责任人名称
        YxCsUserEntity userEntity = uerMapper.selectById(dto.getLeaderId());
        if(null!=userEntity){
            entity.setLeaderName(userEntity.getUserName());
        }
        //渠道名称
        YxCsChannelEntity channelEntity = channelMapper.selectById(dto.getChannelId());
        if(null!=channelEntity){
            entity.setChannelName(channelEntity.getChannelName());
            entity.setChannelCode(channelEntity.getChannelCode());
        }
        groupMapper.updateById(entity);
        //更新用户组
        groupMapper.deleteGroupUserByGroupId(dto.getId());
        groupMapper.addGroupUser(dto.getId(),dto.getUserIdList());
        //禁用/启用addWorkflowRule
        if((CommonConstant.ZERO==entity.getStatus() && CommonConstant.ONE==dto.getStatus()) || (CommonConstant.ONE==entity.getStatus() && CommonConstant.ZERO==dto.getStatus())){
            //启用/禁用对应工作组的群
            LambdaUpdateWrapper<YxCsFlockEntity> flockUpdateWrapper = new LambdaUpdateWrapper<>();
            flockUpdateWrapper.eq(true,YxCsFlockEntity::getGroupId,entity.getId())
                    .set(true,YxCsFlockEntity::getStatus,dto.getStatus());
            flockMapper.update(null,flockUpdateWrapper);
            //启用/禁用对应规则
            LambdaUpdateWrapper<YxCsFlowRuleEntity> ruleUpdateWrapper = new LambdaUpdateWrapper<>();
            ruleUpdateWrapper.eq(true,YxCsFlowRuleEntity::getGroupId,entity.getId())
                    .set(true,YxCsFlowRuleEntity::getStatus,dto.getStatus());
            yxCsFlowRuleMapper.update(null,ruleUpdateWrapper);
        }
    }


    /**
     * 删除工作组
     * @param groupId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGroupById(Long groupId) {
        if(null==groupId){
            throw new BaseException("删除主键不能为空");
        }
        //删除工作组数据
        groupMapper.deleteById(groupId);
        //删除工作组组人员
        LambdaUpdateWrapper<YxCsGroupUserEntity> updateUserWrapper = new LambdaUpdateWrapper<>();
        updateUserWrapper.eq(true,YxCsGroupUserEntity::getGroupId,groupId);
        yxCsGroupUserMapper.delete(updateUserWrapper);
        //删除对应工作组的群
        LambdaQueryWrapper<YxCsFlockEntity> flockqueryWrapper = new LambdaQueryWrapper<>();
        flockqueryWrapper.eq(true,YxCsFlockEntity::getGroupId,groupId);
        List<YxCsFlockEntity> yxCsFlockEntities = flockMapper.selectList(flockqueryWrapper);
        if(null!=yxCsFlockEntities && !yxCsFlockEntities.isEmpty()){
            LambdaQueryWrapper<YxCsFlockUserEntity> flockUserWrapper = new LambdaQueryWrapper<>();
            for (YxCsFlockEntity flockEntity: yxCsFlockEntities) {
                //删除群人员
                flockUserWrapper.eq(true,YxCsFlockUserEntity::getFlockId,flockEntity.getId());
                yxCsFlockUserMapper.delete(flockUserWrapper);
                flockUserWrapper.clear();
            }
            //删除群
            flockMapper.deleteBatchIds(yxCsFlockEntities.stream().map(flcok->flcok.getId()).collect(Collectors.toList()));
        }
        //删除对应规则
        LambdaQueryWrapper<YxCsFlowRuleEntity> ruleQuweyWrapper = new LambdaQueryWrapper<>();
        ruleQuweyWrapper.eq(true,YxCsFlowRuleEntity::getGroupId,groupId);
        List<YxCsFlowRuleEntity> yxCsFlowRuleEntities = yxCsFlowRuleMapper.selectList(ruleQuweyWrapper);
        if(null!=yxCsFlowRuleEntities && !yxCsFlowRuleEntities.isEmpty()){
            LambdaQueryWrapper<YxScFlowRuleUserEntity> ruleUserQuweyWrapper = new LambdaQueryWrapper<>();
            for (YxCsFlowRuleEntity flowRuleEntity:yxCsFlowRuleEntities) {
                //删除规则人员
                ruleUserQuweyWrapper.eq(true,YxScFlowRuleUserEntity::getFlowRuleId,flowRuleEntity.getId());
                yxScFlowRuleUserMapper.delete(ruleUserQuweyWrapper);
                ruleUserQuweyWrapper.clear();
            }
            //删除规则
            yxCsFlowRuleMapper.deleteBatchIds(yxCsFlowRuleEntities.stream().map(rule-> rule.getId()).collect(Collectors.toList()));
        }
    }

    /**
     * 工作组分群-工作组列表查询
     * @param dto
     * @return
     */
    @Override
    public PageVO<YxCsGroupVo> getFlockGroupList(GroupQueryDTO dto) {
        Page<YxCsGroupVo> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        List<YxCsGroupVo> list=groupMapper.getFlockGroupList(page,dto);
        return PageUtils.get(page,list);
    }

    /**
     * 工作组启用/禁用
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGroupStatusById(StatusUpdateDTO dto) {
        YxCsGroupEntity yxCsGroupEntity = baseMapper.selectById(dto.getBussId());
        if(null==yxCsGroupEntity){
            throw new BaseException("工作组不存在");
        }
        //启用的时候需要校验是否存在同渠道的工作组，存在就不能启用
        if(CommonConstant.ZERO==dto.getStatus()){
            //查询同渠道工作组
            LambdaQueryWrapper<YxCsGroupEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(true,YxCsGroupEntity::getChannelId,yxCsGroupEntity.getChannelId())
                         .ne(true,YxCsGroupEntity::getStatus,CommonConstant.ZERO)
                        .ne(true,YxCsGroupEntity::getId,dto.getBussId());
            List<YxCsGroupEntity> yxCsGroupEntities = baseMapper.selectList(queryWrapper);
            if(null != yxCsGroupEntities && !yxCsGroupEntities.isEmpty()){
                throw new BaseException("当前工作组所属渠道已存在于其他启用工作组,请删除/禁用对应工作组以后再行启用");
            }
            yxCsGroupEntity.setStatus(dto.getStatus());
            baseMapper.updateById(yxCsGroupEntity);
        }else if(CommonConstant.ONE==dto.getStatus()){
                yxCsGroupEntity.setStatus(dto.getStatus());
                baseMapper.updateById(yxCsGroupEntity);
        }else{
            throw new BaseException("禁用启用状态错误");
        }
        //启用/禁用对应工作组的群
        LambdaUpdateWrapper<YxCsFlockEntity> flockUpdateWrapper = new LambdaUpdateWrapper<>();
        flockUpdateWrapper.eq(true,YxCsFlockEntity::getGroupId,yxCsGroupEntity.getId())
                .set(true,YxCsFlockEntity::getStatus,dto.getStatus());
        flockMapper.update(null,flockUpdateWrapper);
        //启用/禁用对应规则
        LambdaUpdateWrapper<YxCsFlowRuleEntity> ruleUpdateWrapper = new LambdaUpdateWrapper<>();
        ruleUpdateWrapper.eq(true,YxCsFlowRuleEntity::getGroupId,yxCsGroupEntity.getId())
                .set(true,YxCsFlowRuleEntity::getStatus,dto.getStatus());
        yxCsFlowRuleMapper.update(null,ruleUpdateWrapper);
    }

    /**
     * 工作流管理-工作组详情查询
     * @param groupId
     * @return
     */
    @Override
    public YxCsGroupVo getGroupById(Long groupId) {
        YxCsGroupVo vo = new YxCsGroupVo();
        YxCsGroupEntity entity = baseMapper.selectById(groupId);
        BeanUtil.copyProperties(entity,vo);
        //查询工作组成员
        List<MemberVo> userList=groupMapper.getUserList(entity.getId());
        vo.setUserList(userList);
        return vo;
    }
    //--------------------------------------------------------------------------------------------------------------

    /**
     * 校验删除人员是否可以删除
     * @param dto
     */
    private void validataRuleUser(GroupAddDTO dto) {
        ////查询删除人员
        LambdaQueryWrapper<YxCsGroupUserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true,YxCsGroupUserEntity::getGroupId,dto.getId()).
                notIn(true,YxCsGroupUserEntity::getUserId,dto.getUserIdList());
        List<YxCsGroupUserEntity> yxCsGroupUserEntities = yxCsGroupUserMapper.selectList(queryWrapper);
        StringBuffer sbf=new StringBuffer();
        if(null!=yxCsGroupUserEntities && !yxCsGroupUserEntities.isEmpty()){
            //校验人员是否存分配规则没有启用的人接
            List<Long> userIds = yxCsGroupUserEntities.stream().map(user -> user.getUserId()).collect(Collectors.toList());
            List<UserRuleVo> voList=yxCsFlowRuleMapper.getNoUserRuleByIds(userIds);
            if(null!=voList && !voList.isEmpty()){
                for (UserRuleVo vo :voList) {
                    sbf.append("人员【"+vo.getUserName()+"】在渠道【"+vo.getChannelName()+"】、端口【"+vo.getPortName()+"】、服务类型【"+vo.getServiceTypeName()+"】、规则【"+vo.getRuleTypeName()+"】下没有其余启用人员接收,不能修改删除\n");
                }
            }
        }
        if(StringUtils.isNotBlank(sbf.toString())){
            throw  new BaseException(sbf.toString());
        }
    }

    /**
     * 校验工作组名称和渠道
     */
    private void validateGroupInfo(GroupAddDTO dto){
        //校验组名称不能重复
        LambdaQueryWrapper<YxCsGroupEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true,YxCsGroupEntity::getGroupName,dto.getGroupName())
                .eq(true,YxCsGroupEntity::getStatus,CommonConstant.ZERO)
                .ne(null!=dto.getId(),YxCsGroupEntity::getId,dto.getId());
        Integer count = baseMapper.selectCount(queryWrapper);
        if(count>0){
            throw  new BaseException("工作组名称【"+dto.getGroupName()+"】已存在，请修改名称");
        }
        //一个渠道对应一个分组
        queryWrapper.clear();
        queryWrapper.eq(true,YxCsGroupEntity::getChannelId,dto.getChannelId())
                .eq(true,YxCsGroupEntity::getStatus,CommonConstant.ZERO)
                .ne(null!=dto.getId(),YxCsGroupEntity::getId,dto.getId());
        YxCsGroupEntity yxCsGroupEntity = baseMapper.selectOne(queryWrapper);
        if(null!=yxCsGroupEntity){
            throw  new BaseException("该渠道下已存在名叫【"+yxCsGroupEntity.getGroupName()+"】工作组,请重新选择渠道");
        }
        //工作组负责人需要在工作组中
        if(!dto.getUserIdList().contains(dto.getLeaderId())){
            throw  new BaseException("工作组成员未选择工作组负责人");
        }
    }
}
